package com.wf.smartcomm.server.webhook;

import java.io.BufferedReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;

import javax.annotation.Resource;

import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

import com.wf.smartcomm.server.apns.IApnsService;
import com.wf.smartcomm.server.apns.model.Payload;
import com.wf.smartcomm.server.bean.Bill;
import com.wf.smartcomm.server.bean.Payment;
import com.wf.smartcomm.server.bean.User;
import com.wf.smartcomm.server.client.action.BaseAction;
import com.wf.smartcomm.server.model.PushMessage;
import com.wf.smartcomm.server.push.Pusher;
import com.wf.smartcomm.server.service.BillService;
import com.wf.smartcomm.server.service.PaymentService;
import com.wf.smartcomm.server.service.UserService;
import com.wf.smartcomm.server.util.ConstantUtils;
import com.wf.smartcomm.server.util.IdUtils;
import com.wf.smartcomm.server.util.PushUtils;

import net.sf.json.JSONObject;

@Controller
@Scope("prototype")
public class WebHookAction extends BaseAction{
	@Resource
	private BillService billService;
	
	@Resource
	private UserService userService;
	
	@Resource
	private PaymentService paymentService;
	
	private boolean verify(String sign, String text, String key, String input_charset) {
        text = text + key;
        String mysign = DigestUtils.md5Hex(getContentBytes(text, input_charset));
        logger.info("mysign:" + mysign);
        long timeDifference = System.currentTimeMillis() - Long.valueOf(key);
        logger.info("timeDifference:" + timeDifference);
        if (mysign.equals(sign) && timeDifference <= 300000) {
            return true;
        } else {
            return false;
        }
    }
	private boolean verifySign(String sign, String timestamp) {
    	logger.info("sign:" + sign);
    	logger.info("timestamp:" + timestamp);
        return verify(sign, PushUtils.pushConfig.getProperty("appId") + PushUtils.pushConfig.getProperty("appSecret"),
                timestamp, "UTF-8");
    }
	private byte[] getContentBytes(String content, String charset) {
        if (charset == null || "".equals(charset)) {
            return content.getBytes();
        }
        try {
            return content.getBytes(charset);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
        }
    }
    
    public void webhook()throws Exception{
    	    StringBuffer json = new StringBuffer();
    	    String line = null;
    	    try {
    	        BufferedReader reader = request.getReader();
    	        while ((line = reader.readLine()) != null) {
    	            json.append(line);
    	        }
    	    } catch (Exception e) {
    	        e.printStackTrace();
    	    }
    	    JSONObject jsonObj = JSONObject.fromObject(json.toString());
    	    String sign = jsonObj.getString("sign");
    	    String timestamp = jsonObj.getString("timestamp");
    	    boolean status = verifySign(sign, timestamp);
    	    if (status) { //验证成功
    	        response.getWriter().println("success");
    	        Integer transaction_fee = jsonObj.getInt("transaction_fee");
    	        if (transaction_fee != null) {
    	        	 JSONObject optionalJson =  jsonObj.getJSONObject("optional");
    	    	     String billId = optionalJson.getString("billId");
    	    	     String userId = optionalJson.getString("userId");
    	    	     Bill bill = billService.get(billId);
    	    	     if (bill != null && bill.getStatus().equals(ConstantUtils.BILL_STATUS_CREATED)) {
    	    	    	 User user = userService.getUserById(userId);
    	    	    	 if (bill.getPrice().multiply(new BigDecimal(100)).intValue() == transaction_fee) {
    	    	    		 //通知用户支付成功,修改账单状态，生成支付记录
    	    	    		 if (user.getDeviceType().equals(ConstantUtils.DEVICE_TYPE_ANDROID)) {
    	    						Pusher pusher = PushUtils.getClientPusher();
    	    						PushMessage pmsg = new PushMessage();
    	    						pmsg.setPushType(ConstantUtils.PUSH_TYPE_BILLPAY_SUCCESS);
    	    						pusher.push0x20Message(user.getPushId().getBytes(), gson.toJson(pmsg).getBytes());
    	    						pusher.close();
    	    					} else if(user.getDeviceType().equals(ConstantUtils.DEVICE_TYPE_APPLE)){
    	    						IApnsService service = PushUtils.getApnsService();
    	    						Payload payload = new Payload();
    	    						payload.setBadge(0);
    	    						//payload.setSound("default");
    	    						payload.addParam("type", ConstantUtils.PUSH_TYPE_BILLPAY_SUCCESS);
    	    						service.sendNotification(user.getAppleToken(), payload);
    	    					}
    	    	    		 JSONObject detailJson =  jsonObj.getJSONObject("message_detail");
    	    	    		 bill.setStatus(ConstantUtils.BILL_STATUS_PAYED);
    	    	    		 bill.setPayAt(String.valueOf(System.currentTimeMillis()));
    	    	    		 billService.update(bill);
    	    	    		 Payment payment = new Payment();
    	    	    		 payment.setObjectId(IdUtils.uuid());
    	    	    		 payment.setCreatedAt(String.valueOf(System.currentTimeMillis()));
    	    	    		 payment.setUpdateAt(payment.getCreatedAt());
    	    	    		 payment.setBillId(billId);
    	    	    		 payment.setUser(user);
    	    	    		 payment.setHouse(bill.getHouse());
    	    	    		 payment.setFromAt(bill.getFromAt());
    	    	    		 payment.setToAt(bill.getToAt());
    	    	    		 payment.setSum(bill.getPrice());
    	    	    		 String channel = jsonObj.getString("sub_channel_type");
    	    	    		 String thirdOrderCode = "";
    	    	    		 payment.setChannel(channel);
    	    	    		 if (channel.startsWith("WX")) {
    	    	    			 payment.setMethod(ConstantUtils.PAY_METHOD_WX);
    	    	    			 thirdOrderCode = detailJson.getString("transaction_id");
    	    	    		 }else if (channel.startsWith("ALI")) {
								payment.setMethod(ConstantUtils.PAY_METHOD_ALI);
								thirdOrderCode = detailJson.getString("trade_no");
    	    	    		 }else if (channel.startsWith("UN")) {
    	    	    			 payment.setMethod(ConstantUtils.PAY_METHOD_UN);
    	    	    			 thirdOrderCode = detailJson.getString("queryId");
    	    	    		 }
    	    	    		 payment.setThirdOrderCode(thirdOrderCode);
    	    	    		 paymentService.save(payment);
        	    	     }else {
        	    	    	 //通知用户支付金额不对
        	    	    	 if (user.getDeviceType().equals(ConstantUtils.DEVICE_TYPE_ANDROID)) {
 	    						Pusher pusher = PushUtils.getClientPusher();
 	    						PushMessage pmsg = new PushMessage();
 	    						pmsg.setPushType(ConstantUtils.PUSH_TYPE_BILLPAY_FAIL);
 	    						pusher.push0x20Message(user.getPushId().getBytes(), gson.toJson(pmsg).getBytes());
 	    						pusher.close();
 	    					} else if(user.getDeviceType().equals(ConstantUtils.DEVICE_TYPE_APPLE)){
 	    						IApnsService service = PushUtils.getApnsService();
 	    						Payload payload = new Payload();
 	    						payload.setBadge(0);
 	    						//payload.setSound("default");
 	    						payload.addParam("type", ConstantUtils.PUSH_TYPE_BILLPAY_FAIL);
 	    						service.sendNotification(user.getAppleToken(), payload);
 	    					}
						}
    	    	     }
				}
    	    } else { //验证失败
    	    	response.getWriter().println("fail");
    	    }
    }
}
